using Gee;
using Cairo;
using Gtk;

namespace Ribbons {

	/** Set of ribbon buttons packed together. */
	public class ToolPack : Container {

		private Gee.List<BaseButton> _buttons;
		private int[] _widths;

		/** Construction method */
		construct {
			_buttons = new Gee.ArrayList<BaseButton> ();
			
			set_flags (get_flags () | WidgetFlags.NO_WINDOW);

			add_events (Gdk.EventMask.BUTTON_PRESS_MASK
						| Gdk.EventMask.BUTTON_RELEASE_MASK
						| Gdk.EventMask.POINTER_MOTION_MASK);
		}

		/**
		 * Adds a button before all existing buttons.
		 *
		 * @param widget  The button to add.
		 */
		public void PrependButton (BaseButton widget) {
			insert_button (widget, 0);
		}

		/**
		 * Adds a button after all existing buttons.
		 *
		 * @param widget  The button to add.
		 */
		public void append_button (BaseButton widget) {
			insert_button (widget, -1);
		}

		/**
		 * Inserts a button at the specified location.
		 *
		 * @param widget        The button to add.
		 * @param button_index  The index (starting at 0) at which the button must
		 *                      be inserted, or -1 to insert the button after all
		 *                      existing buttons.
		 */
		public void insert_button (BaseButton widget, int button_index) {
			widget.set_parent (this);
			widget.visible = true;

			widget.draw_background = true;

			if (button_index == -1 || button_index == _buttons.size) {
				if (_buttons.size == 0) {
					widget.group_style = GroupStyle.ALONE;
				} else {
					widget.group_style = GroupStyle.RIGHT;

					if (_buttons.size == 1) {
						_buttons[_buttons.size - 1].group_style = GroupStyle.LEFT;
					} else if (_buttons.size > 1) {
						_buttons[_buttons.size - 1].group_style = GroupStyle.CENTER;
					}
				}
				_buttons.add (widget);
			} else {
				if (button_index == 0) {
					_buttons[_buttons.size - 1].group_style = GroupStyle.LEFT;
					if (_buttons.size == 1) {
						_buttons[0].group_style = GroupStyle.RIGHT;
					} else {
						_buttons[0].group_style = GroupStyle.CENTER;
					}
				}
				_buttons.insert (button_index, widget);
			}

			show_all ();
		}

		/**
		 * Removes the button at the specified index.
		 *
		 * @param button_index  Index of the button to remove.
		 */
		public void remove_button (int button_index) {
			_buttons[button_index].parent = null;

			if (button_index == 0) {
				if (_buttons.size > 1) {
					if (_buttons.size > 2) {
						_buttons[0].group_style = GroupStyle.LEFT;
					} else {
						_buttons[0].group_style = GroupStyle.ALONE;
					}
				}
			} else if (button_index == _buttons.size - 1) {
				if (_buttons.size > 1) {
					if (_buttons.size > 2) {
						_buttons[0].group_style = GroupStyle.RIGHT;
					} else {
						_buttons[0].group_style = GroupStyle.ALONE;
					}
				}
			}
			_buttons.remove_at (button_index);

			show_all ();
		}

		protected override void forall_internal (bool include_internals,
		                                         Gtk.Callback callback)
		{
			foreach (var button in _buttons) {
				if (button.visible) {
					callback (button);
				}
			}
		}
		
		protected override void size_request (out Requisition requisition) {
//			base.size_request (out requisition);	// XXX-GEETK

			if (_widths == null || _widths.length != _buttons.size) {
				_widths = new int[_buttons.size];
			}

			requisition.height = requisition.width = 0;
			int i = 0;
			foreach (var button in _buttons) {
				Gtk.Requisition req;
				button.size_request (out req);
				if (requisition.height < req.height) {
					requisition.height = req.height;
				}
				requisition.width += req.width;
				_widths[i++] = req.width;
			}
			if (this.height_request != -1) {
				requisition.height = this.height_request;
			}
			if (this.width_request != -1) {
				requisition.width = this.width_request;
			}
		}

		protected override void size_allocate (Gdk.Rectangle allocation) {
			base.size_allocate (allocation);

			int i = 0, x = allocation.x;
			foreach (var button in _buttons) {
				var r = Gdk.Rectangle () {
					x = x,
					y = allocation.y,
					width = _widths[i],
					height = allocation.height
				};
				button.size_allocate (r);
				x += r.width;
				++i;
			}
		}

		internal override void remove (Widget widget) {
			// XXX-GEETK
		}
	}
}

